package com.wechat.user.service;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wechat.common.security.token.TokenUtil;
import com.wechat.common.web.exception.BusinessException;
import com.wechat.common.web.result.ResultCode;
import com.wechat.user.constant.RedisKey;
import com.wechat.user.entity.User;
import com.wechat.user.mapper.UserMapper;
import com.wechat.user.request.LoginPhoneRequest;
import com.wechat.user.response.LoginResponse;
import com.wechat.user.util.PasswordEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;

@Slf4j
@Service
public class LoginService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private TokenUtil tokenUtil;

    @Autowired
    private PasswordEncoder passwordEncoder;

    public LoginResponse loginPhone(LoginPhoneRequest request) {
        // 1. 判断用户合法性
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>();
        queryWrapper.eq(User::getPhone, request.getPhone());
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }
        if (!User.Status.NORMAL.getCode().equals(user.getStatus())) {
            throw new BusinessException(ResultCode.USER_DISABLED);
        }
        // 2. 校验密码
        if (!passwordEncoder.checkPassword(request.getPassword(), user.getPassword())) {
            throw new BusinessException(ResultCode.PASSWORD_ERROR);
        }
        // 3. 生成token
        String accessToken = tokenUtil.generateToken(user.getUserId());
        String refreshToken = tokenUtil.generateRefreshToken(user.getUserId());
        // 4. 缓存用户信息到redis
        stringRedisTemplate.opsForValue().set(RedisKey.LOGIN_USER_INFO + user.getUserId(),
                JSON.toJSONString(user), Duration.ofSeconds(tokenUtil.getRefreshExpirationTime()));
        // 5. 返回token
        LoginResponse loginResponse = new LoginResponse();
        loginResponse.setAccessToken(accessToken);
        loginResponse.setRefreshToken(refreshToken);
        // TODO: 选择 netty的服务
        return loginResponse;
    }

}
